#!/bin/bash

# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# This script selects a profile from the overlays.

# Load common CrOS utilities.  Inside the chroot this file is installed in
# /usr/lib/crosutils.  Outside the chroot we find it relative to the scripts
# location.
common_paths="/usr/lib/crosutils $(dirname "$0")/../../../scripts"

for path in ${common_paths} ; do
  if [ -f "${path}/common.sh" ] ; then
    COMMON_SH="${path}/common.sh"
    break
  fi
done

if [ -z "${COMMON_SH}" ] ; then
  echo "common.sh not found in search path (${common_paths})"
  exit 1
fi

. "${COMMON_SH}"
. "${SRC_ROOT}/platform/dev/toolchain_utils.sh"

# Flags
DEFINE_string board "$DEFAULT_BOARD" "The name of the board to set up."
# TODO(bsimonnet): Remove this once setup_board has been updated.
DEFINE_string board_overlay "" "Deprecated. DO NOT USE THIS."
DEFINE_string variant "" "Board variant."
DEFINE_string profile "" "The portage configuration profile to use."
DEFINE_string board_root "" "Board root where the profile should be created."
DEFINE_string brick "" "Brick to set up."

# Parse command line flags
FLAGS "$@" || exit 1
eval set -- "${FLAGS_ARGV}"

# Only now can we die on error.  shflags functions leak non-zero error codes,
# so will die prematurely if 'set -e' is specified before now.
set -e

if [[ -z "${FLAGS_board}" ]] && [[ -z "${FLAGS_brick}" ]] && \
  [[ -z "${FLAGS_board_root}" ]]; then
  error "--board, --brick or --board_root required."
  exit 1
elif [[ -n "${FLAGS_board}" ]] && [[ -n "${FLAGS_brick}" ]]; then
  error "--board and --brick are incompatible."
  exit 1
fi

get_board_and_variant "${FLAGS_board}" "${FLAGS_variant}" "${FLAGS_brick}"

BOARD_ROOT="${FLAGS_board_root:-/build/${BOARD_VARIANT}}"
CHROMIUMOS_OVERLAY="/usr/local/portage/chromiumos"
CHROMIUMOS_PROFILES="${CHROMIUMOS_OVERLAY}/profiles"
MAKE_PROFILE="${BOARD_ROOT}/etc/portage/make.profile"
SYSROOT_CACHE="${BOARD_ROOT}/${SYSROOT_SETTINGS_FILE}"

if [ -e "${MAKE_PROFILE}" -a ! -L "${MAKE_PROFILE}" ]; then
  error "${MAKE_PROFILE} is not a symbolic link, it should be."
  exit 1
fi
# Clean old profile paths.  No need to migrate since we're creating it.
# http://brbug.com/1098
sudo rm -f "${BOARD_ROOT}/etc/make.profile"

#
# Get board overlay list.
#
BOARD_OVERLAY_LIST="$(get_sysroot_config "${BOARD_ROOT}" "BOARD_OVERLAY")"

#
# Get ARCH
#
ARCH=$(get_sysroot_config "${BOARD_ROOT}" "ARCH") || exit 1

# The profile directory comes from many possible locations, the <overlay>
# values below can be any of the board overlays, public, private, primary
# or variant.  The name defaults to base, but can be set using --profile:
#  * relative profile name from --profile in <overlay>/profiles/<name>
#  * absolute profile path from --profile
#  * <overlay>/profiles/base
#  * ${CHROMIUMOS_PROFILES}/default/linux/${ARCH}/10.0/chromeos
#
# If --profile is non-null and does not exist the script will error
# If none of the directories exist the script will error as well
PROFILES_LIST=""
PROFILES_DIR=""
PROFILE_NAME="base"

PROFILE_OVERRIDE="${FLAGS_profile:-$(get_variable "${SYSROOT_CACHE}" \
  "PROFILE_OVERRIDE")}"

if [ ! -z "${PROFILE_OVERRIDE}" ]; then  # profile specified. must exist or we fail
  if [ -d "${PROFILE_OVERRIDE}" ]; then
    PROFILES_DIR="${PROFILE_OVERRIDE}"
  else
    PROFILE_NAME="${PROFILE_OVERRIDE}"
  fi
fi

if [ -z "${PROFILES_DIR}" ]; then
  # Add the overlays in reverse order so that the most specific overlay is
  # searched first.
  for overlay in ${BOARD_OVERLAY_LIST}; do
    PROFILES_LIST="${overlay}/profiles/${PROFILE_NAME} ${PROFILES_LIST}"
  done

  # Then, if we are looking for the default profile, we look in the
  # chromiumos-overlay as well.
  CHROMEOS_PROFILE="${CHROMIUMOS_PROFILES}/default/linux/${ARCH}/10.0/chromeos/"

  if [ "${PROFILE_NAME}" == "base" ]; then
    PROFILES_LIST="${PROFILES_LIST} ${CHROMEOS_PROFILE}"
  fi

  # Search for the most specific profile.  Stop looking once we've found the
  # first one.
  for profile in ${PROFILES_LIST}; do
    if [ -d "${profile}" ]; then
      PROFILES_DIR="${profile}"
      break
    fi
  done
fi

if [ -z "${PROFILES_DIR}" ]; then
  error "Profiles directory not found, searched in (${PROFILES_LIST})"
  exit 1
fi

info "Selecting profile: ${PROFILES_DIR} for ${BOARD_ROOT}"

if [ ! -f "${PROFILES_DIR}/parent" ]; then
  warn "Portage profile directory '${PROFILES_DIR}' has no file 'parent'."
  warn "This likely means your profile directory is invalid and build_packages"
  warn "will fail"
fi

# Only run `ln` if profile doesn't exist, or has changed.
CURR_PROFILE=$(readlink "${MAKE_PROFILE}" 2>/dev/null || :)
if [[ ${CURR_PROFILE} != "${PROFILES_DIR}" ]]; then
  if [[ -n ${CURR_PROFILE} ]]; then
    # If it's changed, then warn & clean out the old link.
    msg="
You are switching profiles for a board that is already setup.  This
can cause trouble for Portage.  If you experience problems with
build_packages you may need to run:
\tsetup_board --board ${BOARD_VARIANT} --force --profile ${PROFILE_NAME}\n
Alternatively, you can correct the dependecy graph by using
'emerge-${BOARD_VARIANT} -c' or 'emerge-${BOARD_VARIANT} -C <ebuild>'
"
    warn "${msg}"
    sudo rm -f "${MAKE_PROFILE}"
  fi

  sudo ln -sf "${PROFILES_DIR}" "${MAKE_PROFILE}"
  if [[ -n "${PROFILE_OVERRIDE}" ]]; then
    set_variable "${SYSROOT_CACHE}" "PROFILE_OVERRIDE" "${PROFILE_OVERRIDE}"
  fi
fi
